package com.wudao.ncmplay.util;


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * String工具类
 * 
 */
public class StringUtil
{
    private static final Logger LOGGER = LogManager.getLogger(StringUtil.class);

    /**
     * 验证email地址是否合法
     * 
     * @param address
     * @return
     */
    public static boolean isValidEmailAddress(String address) {
        if (address == null) {
            return false;
        }

        Pattern p = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
        Matcher m = p.matcher(address);
        return m.find();
    }

    /**
     * 判断字符串是否为空。
     * 
     * @param src
     * @return
     */
    public static boolean isNullOrEmpty(String src) {
        return src == null || src.trim().isEmpty();
    }

    /**
     * 字符串不为空
     * 
     * @param src
     * @return
     */
    public static boolean isNotNullAndEmpty(String src) {
        return !isNullOrEmpty(src);
    }

    private static boolean isEmojiCharacter(char codePoint)
    {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    public static String filterEmoji(String source)
    {
        if (isNullOrEmpty(source))
        {
            return source;
        }

        StringBuilder buf = null;
        int len = source.length();
        for (int i = 0; i < len; i++)
        {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint))
            {
                if (buf == null)
                {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }
        if (buf == null)
        {
            return source;
        }
        else
        {
            if (buf.length() == len)
            {
                buf = null;
                return source;
            }
            else
            {
                return buf.toString();
            }
        }
    }

    /**
     * 判断字符串是否为空或者只包含空格。
     * 
     * @param src
     * @return
     */
    public static boolean isEmptyOrWhitespaceOnly(String src)
    {
        if (isNullOrEmpty(src)) {
            return true;
        }

        if (src.trim().length() == 0) {
            return true;
        }

        return false;
    }

    /**
     * 判断字符串是否超过最大长度
     * 
     * @param rawStr
     * @param maxLen
     * @return
     */
    public static String verifyMaxLen(String rawStr, int maxLen)
    {
        if (rawStr == null || rawStr.trim().length() == 0) {
            return rawStr;
        }
        if (rawStr.length() > maxLen) {
            return rawStr.substring(0, maxLen);
        }
        return rawStr;
    }

    public static void geneteCheckImg(int[] checkCodeSet, int width, int height)
    {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        Random random = new Random();
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Time New Roman", Font.PLAIN, 60));
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 100; i++)
        {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(12);
            int y1 = random.nextInt(12);
            g.drawLine(x, y, x + x1, y + y1);
        }

        for (int i = 0; i < checkCodeSet.length; i++)
        {
            int j = checkCodeSet[i];
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            g.drawString(j + "", 30 * i + 10, 66);
        }
    }

    private static Color getRandColor(int fc, int bc)
    {
        Random random = new Random();
        if (fc > 255)
        {
            fc = 255;
        }
        if (bc > 255)
        {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    /**
     * 获取字符串的长度，如果有中文，则每个中文字符计为2位
     * 
     * @param value
     *            指定的字符串
     * @return 字符串的长度
     */
    public static int length(String value)
    {
        int valueLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        /* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
        for (int i = 0; i < value.length(); i++)
        {
            /* 获取一个字符 */
            String temp = value.substring(i, i + 1);
            /* 判断是否为中文字符 */
            if (temp.matches(chinese))
            {
                /* 中文字符长度为2 */
                valueLength += 2;
            }
            else
            {
                /* 其他字符长度为1 */
                valueLength += 1;
            }
        }
        return valueLength / 2;
    }

    /**
     * <pre>
     * 是否为数字类型(负数返回false)
     * </pre>
     * 
     * @param str
     * @return
     */
    public static boolean isNumber(String str)
    {
        if (!isNullOrEmpty(str) && str.matches("\\d*"))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public static boolean isInteger(String str)
    {
        if (str == null || str.isEmpty())
            return false;

        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    /**
     * 判断浮点数（double和float）
     * 
     * @param str
     * @return
     */
    public static boolean isDouble(String str)
    {
        if (isNullOrEmpty(str))
        {
            return false;
        }
        Pattern pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*[dDfF]{0,1}");

        // Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
        return pattern.matcher(str).matches();
    }

    /**
     * 
     * <pre>
     * 通过ascii做非空判断
     * </pre>
     *
     * @param str
     * @return
     */
    public static boolean isContainsSpace(String str)
    {
        if (str == null)
        {
            return true;
        }

        char[] b = str.toCharArray();

        for (int i = 0; i < b.length; i++)
        {
            if ((int) b[i] == 32)
            {
                return true;
            }
        }
        return false;
    }

    /**
     * 查找正则
     * 
     * @param content
     * @param regex
     * @return
     */
    public static List<String> find(String content, String regex)
    {
        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.MULTILINE);
        Matcher m = pattern.matcher(content);

        List<String> vals = new ArrayList<>();

        while (m.find())
        {
            for (int i = 0; i < m.groupCount(); ++i)
            {
                vals.add(m.group(i));
            }
        }

        return vals;
    }

    /**
     * 
     * @param content
     * @param regex
     * @return
     */
    public static String findFirst(String content, String regex)
    {
        try
        {
            List<String> vals = find(content, regex);
            return vals.size() < 2 ? null : vals.get(1);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * generate a string
     * 
     * @param len
     * @return
     */
//    public static String randomString(int len)
//    {
//        String total = "";
//
//        while (total.length() < len)
//        {
//            long time = System.currentTimeMillis() << 4;
//            time += (long) (Math.random() * 10000);
//            total += MD5Util.md5(String.valueOf(time));
//        }
//
//        return total.substring(0, len);
//    }

    /**
     * @param recruitIDs
     * @param string
     * @return
     */
    public static Set<Integer> splitInt(String val, String del)
    {
        Set<Integer> vals = new HashSet<>();

        try
        {
            if (val != null && !val.isEmpty())
            {
                String[] v = val.split(del);
                for (String i : v)
                {
                    if (isInteger(i))
                        vals.add(Integer.parseInt(i.trim()));
                }
            }
        }
        catch (Exception e)
        {
            LOGGER.error("", e);
        }

        return vals;
    }

    public static List<Integer> splitIntToList(String val, String del)
    {
        List<Integer> vals = new ArrayList<>();

        try
        {
            if (val != null && !val.isEmpty())
            {
                String[] v = val.split(del);
                for (String i : v)
                {
                    if (isInteger(i))
                        vals.add(Integer.parseInt(i.trim()));
                }
            }
        }
        catch (Exception e)
        {
            LOGGER.error("", e);
        }

        return vals;
    }

    public static List<String> splitStringToList(String val, String del)
    {
        List<String> vals = new ArrayList<>();

        try
        {
            if (val != null && !val.isEmpty())
            {
                String[] v = val.split(del);
                for (String i : v)
                {
                    if (i != "" && !i.trim().isEmpty())
                        vals.add(i.trim());
                }
            }
        }
        catch (Exception e)
        {
            LOGGER.error("", e);
        }

        return vals;
    }

    /**
     * 合并int集
     * 
     * @param vals
     * @return
     */
    public static String mergeInt(Set<Integer> vals)
    {
        String val = "";

        for (Integer v : vals)
        {
            val += v + ",";
        }

        if (val.endsWith(","))
        {
            val = val.substring(0, val.length() - 1);
        }

        return val;
    }

    public static String mergeInt(List<Integer> value)
    {
        StringBuilder val = new StringBuilder();
        StringBuilder finalVal = val;
        value.forEach(obj-> finalVal.append(",").append(obj));
        return finalVal.toString().replaceFirst(",","");
    }

    /**
     * 取得字符串中的数字
     *
     * @author Lin Heng
     * @param str
     * @return
     */
    public static String getNumberFromString(String str) {
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    /******************************* 匹配相似度 ******************************/

    /**
     * 比较两个字符串的相识度
     * 核心算法：用一个二维数组记录每个字符串是否相同，如果相同记为0，不相同记为1，每行每列相同个数累加
     * 则数组最后一个数为不相同的总数，从而判断这两个字符的相识度
     *
     * @author Lin Heng
     * @param str
     * @param target
     * @return
     */
    private static int compare(String str, String target) {
        int d[][];              // 矩阵
        int n = str.length();
        int m = target.length();
        int i;                  // 遍历str的
        int j;                  // 遍历target的
        char ch1;               // str的
        char ch2;               // target的
        int temp;               // 记录相同字符,在某个矩阵位置值的增量,不是0就是1

        if (n == 0) {
            return m;
        }
        if (m == 0) {
            return n;
        }
        d = new int[n + 1][m + 1];

        // 初始化第一列
        for (i = 0; i <= n; i++) {
            d[i][0] = i;
        }

        // 初始化第一行
        for (j = 0; j <= m; j++) {
            d[0][j] = j;
        }

        for (i = 1; i <= n; i++) {
            // 遍历str
            ch1 = str.charAt(i - 1);
            // 去匹配target
            for (j = 1; j <= m; j++) {
                ch2 = target.charAt(j - 1);
                if (ch1 == ch2 || ch1 == ch2 + 32 || ch1 + 32 == ch2) {
                    temp = 0;
                }else {
                    temp = 1;
                }
                // 左边+1,上边+1, 左上角+temp取最小
                d[i][j] = minNum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + temp);
            }
        }
        return d[n][m];
    }

    /**
     * 获取最小的值
     *
     * @author Lin Heng
     * @param one
     * @param two
     * @param three
     * @return
     */
    public static int minNum(int one, int two, int three) {
        return (one = Math.min(one, two)) < three ? one : three;
    }

    /**
     * @Description 获取最大的值
     *
     * @author ZhengGuoFen
     * @Date  2022/6/13
     * @param one
     * @param two
     * @param three
     * @return
     **/
    public static int maxNum(int one, int two, int three){
        return (one = Math.max(one, two)) > three ? one : three;
    }

    /**
     * 获取两字符串的相似度
     * @author Lin Heng
     * @param str 原字符串
     * @param target 目标字符串
     */
    public static float getSimilarityRatio(String str, String target) {
        int max = Math.max(str.length(), target.length());
        return 1 - (float) compare(str, target) / max;
    }

    /**
     * 随机密码
     *
     * @author Lin Heng
     * @return
     */
    public static String randomPassword()
    {
        int i = (int) (Math.random() * 26);
        int j = (int) 'A' + i;
        char ch = (char) j;
        int i2 = (int) (Math.random() * 26);
        int j2 = (int) 'A' + i2;
        char ch2 = (char) j2;
        int nextInt = (int) ((Math.random() * 9 + 1) * 10000);
        String str = ch + "" + ch2 + "" + nextInt;
        char[] charArray = str.toCharArray();
        for (int k = 0; k < charArray.length; k++) {
            if (charArray[k] == 'O') {
                charArray[k] = 'A';
            }
            if (charArray[k] == '0') {
                charArray[k] = '1';
            }
        }
        str = String.copyValueOf(charArray);
        return str;
    }

    /**
     * @Description 转换中文数字
     *
     * @author ZhengGuoFen
     * @Date  2022/6/13
     * @param
     * @return
     **/
    public static String int2String(int number) {
        String str = "";
        switch (number)
        {
        case 1:
            str = "一";
            break;
        case 2:
            str = "二";
            break;
        case 3:
            str = "三";
            break;
        case 4:
            str = "四";
            break;
        case 5:
            str = "五";
            break;
        case 6:
            str = "六";
            break;
        case 7:
            str = "七";
            break;
        case 8:
            str = "八";
            break;
        case 9:
            str = "九";
            break;
        case 10:
            str = "十";
            break;
        default:
            break;
        }
        return str;
    }

    /**
     * @Description emoji表情转换
     *
     * @author Lin Heng
     * @param str 待转换字符串
     * @return 转换后字符串
     */
    public static String emojiConvertToUtf(String str) {
        String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";

        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            try {
                matcher.appendReplacement(sb, " ");
            } catch (Exception e) {
                LOGGER.error("转换错误", e);
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 判断组合字符串里是否存在指定值
     *
     * @auther Lin Heng
     * @param source 原字符串
     * @param split 分割符
     * @param value 指定值
     * @return boolean
     *      true 是
     *      false 否
     */
    public static boolean isContain(String source, String split, int value) {
        List<Integer> list = splitIntToList(source, split);
        return list.contains(value);
    }
}
